﻿using ManagementSystem.App_LocalResources;
using ManagementSystem.Areas.BMS.Models.Function;
using ManagementSystem.Filter;
using ManagementSystem.Models;
using MS.Entities;
using MS.Enums.Common;
using MS.Identity;
using MS.Logic;
using MS.Utility.Common;
using MS.Utility.EF;
using MS.Utility.EnumHelper;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace ManagementSystem.Areas.BMS.Controllers
{
    [LoginFilter(Platform.BMS)]
    public class FunctionController : Controller
    {
        /// <summary>
        /// 菜单管理列表
        /// </summary>
        /// <returns></returns>
        // GET: BMS/Function
        public ActionResult Index()
        {
            return View();
        }
        /// <summary>
        /// 功能菜单列表
        /// </summary>
        /// <returns></returns>
        public ActionResult List()
        {
            int id = Convert.ToInt32(RouteData.Values["id"]);
            MS_Base_FunctionLogic functionLogic = MS_Base_FunctionLogic.GetInstance();
            var function = functionLogic.GetItemByQuery(x => x.Id == id && x.Status == (int)Status.Normal);
            if(function == null)
            {
                HttpContext.Response.Redirect("/BMS/Error/404");
            }

            return View(function);
        }

        #region 获取页面数据
        /// <summary>
        /// 获取功能列表
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult GetList(string name = "",int type = 0,int pid = -1)
        {
            MS_Base_FunctionLogic functionLogic = MS_Base_FunctionLogic.GetInstance();
            MS_UserCenter_UserAttrLogic userAttrLogic = MS_UserCenter_UserAttrLogic.GetInstance();
            //int totalRecords = 0;
            Expression<Func<MS_Base_Function, bool>> expression = PredicateBuilder.True<MS_Base_Function>();
            expression = expression.And(x => x.Status == (int)Status.Normal && x.Type == type);
            if (!string.IsNullOrEmpty(name))
            {
                expression = expression.And(x => x.Name.Contains(name));
            }
            if(pid > -1)
            {
                expression = expression.And(x => x.Pid == pid);
            }


            JsonResultModel model = new JsonResultModel();
            List<MS_Base_Function> list = functionLogic.GetListByQuery(expression, "Pid,SeqId", false);
            long[] uidArr = list.Select(x => x.UpdateUid == 0 ? x.CreateUid : x.UpdateUid).ToArray();
            List<MS_UserCenter_UserAttr> userList = userAttrLogic.GetListByQuery((x => uidArr.Contains(x.Uid)), string.Empty, false);

            
            //列表数据
            var tableJsonList = from o in list
                                select new
                                {
                                    id = o.Id,
                                    pid = o.Pid,
                                    name = Utils.ToHtml(o.Name),
                                    url = o.Url,
                                    path = o.Path,
                                    iconClassName = Utils.ToHtml(o.IconClassName),
                                    type = o.Type,
                                    type_name = EnumHelper.GetEnumDescription((FunctionType)o.Type),
                                    lastTime = DateTimeHelper.GetDateTime(o.UpdateTime.ToString()).ToString("yyyy-MM-dd HH:mm:ss"),
                                    lastUser = from u in userList where u.Uid == o.UpdateUid select string.IsNullOrEmpty(u.RealName) ? Utils.Htmls(u.NickName) : Utils.Htmls(u.RealName),
                                    isAllowUp = o.SeqId != list.First(x=>x.Pid == o.Pid).SeqId,
                                    isAllowDown = o.SeqId != list.Last(x=>x.Pid == o.Pid).SeqId,
                                    isShowAdd = !list.Exists(x=>x.Pid == o.Id)
                                };
            
            //下拉菜单数据模型
            List<MenuSelectModel> menuJsonList = (from o in list
                                            where o.Pid == 0
                                            select new MenuSelectModel()
                                            {
                                                id = o.Id,
                                                pid = o.Pid,
                                                name = Utils.ToHtml(o.Name),
                                                child = new List<MenuSelectModel>()
                                            }).ToList();
            foreach (MenuSelectModel menu in menuJsonList)
            {
                menu.pathName = ">";
                GetMenuChild(menu,list,menu.name);
            }


            model.code = Code.SUCCESS;
            model.message = Message.SUCCESS;
            //列表数据
            if (list.Count > 0)
            {
                model.data = new
                {
                    tableData = tableJsonList,
                    menuSelectData = menuJsonList
                };
            }
            else
            {
                model.data = new
                {
                    tableData = list,
                    menuSelectData = list
                };
            }
            
            //下拉菜单数据

            return Json(model);
        }
        /// <summary>
        /// 递归函数，获取菜单
        /// </summary>
        /// <param name="menu"></param>
        /// <param name="list"></param>
        private void GetMenuChild(MenuSelectModel menu, List<MS_Base_Function> list, string pathName)
        {
            List<MenuSelectModel> child = (from o in list
                                           where o.Pid == menu.id && o.Type == (int)FunctionType.Menu
                                           select new MenuSelectModel()
                                           {
                                               id = o.Id,
                                               pid = o.Pid,
                                               name = Utils.ToHtml(o.Name),
                                               child = new List<MenuSelectModel>()
                                           }).ToList();
            if (child.Count == 0)
            {
                return;
            }
            foreach (MenuSelectModel c in child)
            {
                c.pathName = pathName + ">";
                menu.child.Add(c);
                GetMenuChild(c, list, c.pathName + c.name);
            }
        }
        #endregion

        #region 保存菜单或者功能
        /// <summary>
        /// 保存菜单或者功能
        /// </summary>
        /// <param name="id">id为0代变新增，有值代变编辑</param>
        /// <param name="pid">上级id</param>
        /// <param name="name">名称</param>
        /// <param name="url">url地址</param>
        /// <param name="iconClassName">图标类名称</param>
        /// <param name="type">类型 对应枚举FunctionType </param>
        /// <returns></returns>
        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Save(int id,int pid,string name,string url ,string iconClassName,int type)
        {
            JsonResultModel model = new JsonResultModel();
            MS_Base_FunctionLogic functionLogic = MS_Base_FunctionLogic.GetInstance();
            long loginUid = SecurityIdentity.GetLoginUid(Platform.BMS);
            int res = functionLogic.Save(id, pid, name, url, (FunctionType)type, iconClassName,loginUid);

            model.code = Code.SUCCESS;
            model.message = Message.SUCCESS;
            model.data = res;
            return Json(model);
        }
        #endregion

        #region 删除菜单或者功能
        /// <summary>
        /// 删除菜单或者功能
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Delete(int id)
        {
            MS_Base_FunctionLogic functionLogic = MS_Base_FunctionLogic.GetInstance();
            MS_Base_RoleFunctionLogic roleFunctionLogic = MS_Base_RoleFunctionLogic.GetInstance();

            JsonResultModel model = new JsonResultModel();
            if (id<=0)
            {
                model.code = Code.ERROR;
                model.message = Message.PARAMERROR;
                model.data = new { };
                return Json(model);
            }
          
            /**
            * id允许被删除的规则如下：
            * 1、没有下级节点
            * 2、没有被RoleFunction引用
            */
            if(functionLogic.IsExists(x=>x.Pid == id && x.Status == (int)Status.Normal))
            {
                model.code = Code.ERROR;
                model.message = Message.ERROR;
                model.data = "该菜单下有子菜单或功能，请先删除子菜单或功能。";
                return Json(model);
            }
            if(roleFunctionLogic.IsExists(x=>x.FunctionId == id && x.Status == (int)Status.Normal))
            {
                model.code = Code.ERROR;
                model.message = Message.ERROR;
                model.data = "该菜单已关联角色，请先取消关联。";
                return Json(model);
            }
            long uid = SecurityIdentity.GetLoginUid(Platform.BMS);
            MS_Base_Function function = functionLogic.GetById(id);
            if(function == null)
            {
                model.code = Code.ERROR;
                model.message = Message.ERROR;
                model.data = "未找到对应id的菜单或功能。";
                return Json(model);
            }
            function.Status = (int)Status.Delete;
            function.UpdateTime = DateTimeHelper.GetTime(DateTime.Now);
            function.UpdateUid = uid;
            functionLogic.Save(function);
            
            model.code = Code.SUCCESS;
            model.message = Message.SUCCESS;
            model.data = new { };
            return Json(model);
        }
        #endregion

        #region 移动排序
        /// <summary>
        /// 移动排序
        /// </summary>
        /// <param name="id"></param>
        /// <param name="way">移动的方向 1 向上 2向下</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Move(int id,int way)
        {
            MS_Base_FunctionLogic functionLogic = MS_Base_FunctionLogic.GetInstance();
            JsonResultModel model = new JsonResultModel();
            if (id <= 0)
            {
                model.code = Code.ERROR;
                model.message = Message.PARAMERROR;
                model.data = "";
                return Json(model);
            }
            long loginUid = SecurityIdentity.GetLoginUid(Platform.BMS);
            bool b = functionLogic.Move(id, (MoveWay)way, loginUid);
            if (b)
            {
                model.code = Code.SUCCESS;
                model.message = Message.SUCCESS;
                model.data = new { };
            }
            else
            {
                model.code = Code.ERROR;
                model.message = Message.ERROR;
                switch (way)
                {
                    case (int)MoveWay.Up:
                        model.data = "已经到最顶端了";
                        break;
                    case (int)MoveWay.Down:
                        model.data = "已经到最底部了";
                        break;
                    default:
                        model.data = "";
                        break;
                }
                
            }


            
            return Json(model);
        }
        #endregion
    }
}